package com.example.controller;

import com.example.common.Result;
import com.example.dto.AdminLoginDTO;
import com.example.dto.AdminProfileDTO;
import com.example.dto.ChangePasswordDTO;
import com.example.entity.Admin;
import com.example.service.AdminService;
import com.example.utils.JwtUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * 管理员控制器
 */
@Slf4j
@RestController
@RequestMapping("/api/admin")
@RequiredArgsConstructor
@Tag(name = "管理员管理", description = "管理员相关接口")
public class AdminController {

    private final AdminService adminService;
    private final JwtUtils jwtUtils;

    @PostMapping("/login")
    @Operation(summary = "管理员登录")
    public Result<Map<String, Object>> login(@Valid @RequestBody AdminLoginDTO loginDTO, 
                                            HttpServletRequest request) {
        try {
            String clientIp = getClientIp(request);
            Map<String, Object> result = adminService.login(loginDTO, clientIp);
            
            log.info("管理员登录成功: {}, IP: {}", loginDTO.getUsername(), clientIp);
            return Result.success(result);
        } catch (Exception e) {
            log.error("管理员登录失败: {}, 原因: {}", loginDTO.getUsername(), e.getMessage());
            return Result.error("登录失败: " + e.getMessage());
        }
    }

    @PostMapping("/logout")
    @Operation(summary = "管理员退出登录")
    public Result<Void> logout(@AuthenticationPrincipal Admin admin) {
        try {
            adminService.logout(admin.getId());
            log.info("管理员退出登录: {}", admin.getUsername());
            return Result.success();
        } catch (Exception e) {
            log.error("管理员退出登录失败: {}", e.getMessage());
            return Result.error("退出登录失败");
        }
    }

    @GetMapping("/profile")
    @Operation(summary = "获取管理员信息")
    public Result<AdminProfileDTO> getProfile(@AuthenticationPrincipal Admin admin) {
        try {
            AdminProfileDTO profile = adminService.getProfile(admin.getId());
            return Result.success(profile);
        } catch (Exception e) {
            log.error("获取管理员信息失败: {}", e.getMessage());
            return Result.error("获取信息失败");
        }
    }

    @PutMapping("/profile")
    @Operation(summary = "更新管理员信息")
    public Result<Void> updateProfile(@AuthenticationPrincipal Admin admin,
                                     @Valid @RequestBody AdminProfileDTO profileDTO) {
        try {
            adminService.updateProfile(admin.getId(), profileDTO);
            log.info("管理员更新信息: {}", admin.getUsername());
            return Result.success();
        } catch (Exception e) {
            log.error("更新管理员信息失败: {}", e.getMessage());
            return Result.error("更新信息失败");
        }
    }

    @PutMapping("/password")
    @Operation(summary = "修改密码")
    public Result<Void> changePassword(@AuthenticationPrincipal Admin admin,
                                      @Valid @RequestBody ChangePasswordDTO changePasswordDTO) {
        try {
            adminService.changePassword(admin.getId(), changePasswordDTO);
            log.info("管理员修改密码: {}", admin.getUsername());
            return Result.success();
        } catch (Exception e) {
            log.error("修改密码失败: {}", e.getMessage());
            return Result.error("修改密码失败: " + e.getMessage());
        }
    }

    @GetMapping("/list")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    @Operation(summary = "获取管理员列表")
    public Result<Page<Admin>> getAdminList(Pageable pageable,
                                           @RequestParam(required = false) String keyword,
                                           @RequestParam(required = false) Admin.AdminRole role,
                                           @RequestParam(required = false) Admin.AdminStatus status) {
        try {
            Page<Admin> adminPage = adminService.getAdminList(pageable, keyword, role, status);
            return Result.success(adminPage);
        } catch (Exception e) {
            log.error("获取管理员列表失败: {}", e.getMessage());
            return Result.error("获取列表失败");
        }
    }

    @PostMapping
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    @Operation(summary = "创建管理员")
    public Result<Void> createAdmin(@AuthenticationPrincipal Admin currentAdmin,
                                   @Valid @RequestBody Admin admin) {
        try {
            adminService.createAdmin(admin, currentAdmin.getId());
            log.info("创建管理员: {}, 操作人: {}", admin.getUsername(), currentAdmin.getUsername());
            return Result.success();
        } catch (Exception e) {
            log.error("创建管理员失败: {}", e.getMessage());
            return Result.error("创建失败: " + e.getMessage());
        }
    }

    @PutMapping("/{id}")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    @Operation(summary = "更新管理员")
    public Result<Void> updateAdmin(@AuthenticationPrincipal Admin currentAdmin,
                                   @PathVariable Long id,
                                   @Valid @RequestBody Admin admin) {
        try {
            adminService.updateAdmin(id, admin, currentAdmin.getId());
            log.info("更新管理员: {}, 操作人: {}", id, currentAdmin.getUsername());
            return Result.success();
        } catch (Exception e) {
            log.error("更新管理员失败: {}", e.getMessage());
            return Result.error("更新失败: " + e.getMessage());
        }
    }

    @PutMapping("/{id}/status")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    @Operation(summary = "更新管理员状态")
    public Result<Void> updateAdminStatus(@AuthenticationPrincipal Admin currentAdmin,
                                         @PathVariable Long id,
                                         @RequestParam Admin.AdminStatus status) {
        try {
            adminService.updateAdminStatus(id, status, currentAdmin.getId());
            log.info("更新管理员状态: {}, 状态: {}, 操作人: {}", id, status, currentAdmin.getUsername());
            return Result.success();
        } catch (Exception e) {
            log.error("更新管理员状态失败: {}", e.getMessage());
            return Result.error("更新状态失败: " + e.getMessage());
        }
    }

    @DeleteMapping("/{id}")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    @Operation(summary = "删除管理员")
    public Result<Void> deleteAdmin(@AuthenticationPrincipal Admin currentAdmin,
                                   @PathVariable Long id) {
        try {
            adminService.deleteAdmin(id, currentAdmin.getId());
            log.info("删除管理员: {}, 操作人: {}", id, currentAdmin.getUsername());
            return Result.success();
        } catch (Exception e) {
            log.error("删除管理员失败: {}", e.getMessage());
            return Result.error("删除失败: " + e.getMessage());
        }
    }

    @GetMapping("/permissions")
    @Operation(summary = "获取权限列表")
    public Result<Map<String, Object>> getPermissions() {
        try {
            Map<String, Object> permissions = adminService.getAllPermissions();
            return Result.success(permissions);
        } catch (Exception e) {
            log.error("获取权限列表失败: {}", e.getMessage());
            return Result.error("获取权限失败");
        }
    }

    @GetMapping("/dashboard")
    @Operation(summary = "获取仪表板数据")
    public Result<Map<String, Object>> getDashboard(@AuthenticationPrincipal Admin admin) {
        try {
            Map<String, Object> dashboard = adminService.getDashboardData(admin);
            return Result.success(dashboard);
        } catch (Exception e) {
            log.error("获取仪表板数据失败: {}", e.getMessage());
            return Result.error("获取数据失败");
        }
    }

    /**
     * 获取客户端IP地址
     */
    private String getClientIp(HttpServletRequest request) {
        String xForwardedFor = request.getHeader("X-Forwarded-For");
        if (xForwardedFor != null && !xForwardedFor.isEmpty() && !"unknown".equalsIgnoreCase(xForwardedFor)) {
            return xForwardedFor.split(",")[0].trim();
        }
        
        String xRealIp = request.getHeader("X-Real-IP");
        if (xRealIp != null && !xRealIp.isEmpty() && !"unknown".equalsIgnoreCase(xRealIp)) {
            return xRealIp;
        }
        
        return request.getRemoteAddr();
    }
}
